﻿using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.DependencyInjection;
using SH.Common;
using SH.Multitenant.API;
using SH.Multitenant.Domain.Multitenant;
using SH.Multitenant.Domain.RBAC;
using SqlSugar;
using System.Reflection;


namespace SH.Multitenant.Core.Saas
{

    public class DbManger
    {

        /// <summary>
        /// 获取业务库对象 （用IOC这块代码不能写到IOC里面）
        /// </summary>
        public static ISqlSugarClient BizDb
        {
            get
            {
                User user = GetUserInfo();//根据Token获取用户信息和连接字符串信息
                //如果为null 切为默认库
                //if (string.IsNullOrEmpty(user.TenantId))
                //{
                //    return Db.GetConnection("default");
                //}
                var tenantId = user.TenantId.ToString();//集团ID（也可以叫租户ID）
                var options = Db.Queryable<DbOptions>().First(it => it.TenantId == user.TenantId);
                //SqlSugarProvider result;
                if (!Db.IsAnyConnection(tenantId))
                { //用非默认ConfigId进行测试
                  //添加业务库只在当前上下文有效（原理：SqlSugarScope模式入门文档去看）
                  //判断数据库是否存在
                    string conn = options.Conn;
                    Db.AddConnection(new ConnectionConfig()
                    {
                        ConfigId = tenantId,
                        ConnectionString = conn,
                        DbType = DbType.MySql,
                        IsAutoCloseConnection = true,
                        MoreSettings = new ConnMoreSettings
                        {
                            IsAutoDeleteQueryFilter = true,//启用删除查询过滤器  
                            IsAutoUpdateQueryFilter = true//启用更新查询过滤器 （表达式更新，如果是实体方式更新建议先查询在更新）
                        }
                    });
                    //库不存在则建库
                    Db.GetConnection(tenantId).DbMaintenance.CreateDatabase();
                    // 获取解决方案文件夹路径
                    //string solutionDirectory = Directory.GetParent(Directory.GetCurrentDirectory()).FullName;
                    // 获取所有 .cs 文件所在的文件夹
                    //string classesDirectory = Path.Combine(solutionDirectory, "SH.Multitenant.Domain", "RBAC");
                    //判断该目录是否存在
                    //if (Directory.Exists(classesDirectory))
                    //{
                    // 获取所有 .cs 文件
                    //var files = Directory.GetFiles(classesDirectory, "*.cs", SearchOption.AllDirectories);                        
                    Type[] types = typeof(Employee).Assembly.GetTypes().Where(it => it.FullName.Contains("SH.Multitenant.Domain.RBAC")).ToArray();
                    foreach (var type in types)
                    {
                        // 加载 .cs 文件
                        //var assembly = Assembly.LoadFile(file);                        
                        Db.GetConnection(tenantId).CodeFirst.InitTables(type);

                        //var classes = assembly.GetTypes().Where(t => t.IsClass);
                        //foreach (var cls in classes)
                        //{
                        //    //Console.WriteLine(cls.FullName);
                        //    //自动建表
                        //    Db.CodeFirst.InitTables(cls);
                        //}
                    }
                    //}
                }
                //原理说明
                //IsAnyConnection、AddConnection和GetConnection 都是Scope周期不同请求不会有影响

                var result = Db.GetConnection(tenantId);

                //接口过滤器 (继承接口的类都有效) 请升级 5.1.3.47
                Db.QueryFilter.AddTableFilter<Tenant>(it => it.TenantId == user.TenantId);
                //全局设置删除
                //Db.Deleteable<Tenant>().EnableQueryFilter().Where(x => x.TenantId == user.TenantId).ExecuteCommand();

                return result;
            }
        }


        /// <summary>
        /// 获基础信息库对象 （用IOC这块代码不能写到IOC里面）
        /// </summary>
        public static ISqlSugarClient MasterDb
        {
            get
            {
                //如果是跨服务器分库，也需要动态配置的，因为库的IP会变
                //参考业务库用法
                return Db.GetConnection("default");
            }
        }


        //通过IOC获取注入的Db对象
        public static SqlSugarScope Db
        {
            get
            {
                //如果用Furion就是 App.GetService<ISqlSugarClient>();
                //IOC不会可以看文档： https://www.donet5.com/Doc/27/2563
                var ihttp = AppService.Services.BuildServiceProvider().GetService<IHttpContextAccessor>();
                var obj = ihttp?.HttpContext?.RequestServices.GetService<ISqlSugarClient>();
                return (SqlSugarScope)obj;
            }
        }

        /// <summary>
        /// 获取用户数据库连接字符串信息 （从jwt或者ids4）
        /// </summary>
        /// <returns></returns>
        private static User GetUserInfo()
        {
            //判断是租户还是员工
            var user = Db.Queryable<User>().First();
            return user;
        }
    }
}



